package com.hmsproject.db.inmemorydb;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;

import com.hmsproject.datastructures.HotelImage;
import com.hmsproject.datastructures.Hotel;
import com.hmsproject.datastructures.StarValue;
import com.hmsproject.datastructures.deal.Deal;
import com.hmsproject.search.bean.FilterBean;
import com.hmsproject.search.bean.SearchBean;

public class HotelMap {

	private static HotelMap hotelMap = new HotelMap();
	
	private Map<String,Hotel> hotelMapper;
	
    Map<String,Object> map;
	
	private HotelMap(){
		
		
		String filePath = HotelMap.class.getResource("datafile"+InMemoryDBConstants.FILE_SEPARATER+"hotelist.json").getFile();
		
		System.out.println("File Path :: "+filePath);
		
		try{
			processSearchResult(new File(filePath));
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		new HotelMap();
	}
	
	public static HotelMap getInstance(){
		return hotelMap;
	}
	
	private void processSearchResult(File file) throws Exception{
		
		hotelMapper = new HashMap<String,Hotel>();
		
		ObjectMapper mapper = new ObjectMapper();
        
        map = mapper.readValue(file,new TypeReference<HashMap<String,Object>>(){});
        
	}
	
	private void createHotelMap(Map<String,Object> map) throws Exception
	{
		
        Map<String,Object> hotelListResponseMap = (Map<String,Object>)map.get("HotelListResponse");
        
        Map<String,Object> hotelListMap = (Map<String,Object>)hotelListResponseMap.get("HotelList");
        
        if(hotelListMap == null){
        	return;
        }
        
		hotelMapper = new HashMap<String,Hotel>();
        
        String sizeStr = (String)hotelListMap.get("@size");
        
        List<Map<String,Object>> hotelSummaryList = new ArrayList<Map<String,Object>>();

        if(sizeStr.equals("1")){
        	hotelSummaryList.add((Map<String,Object>)hotelListMap.get("HotelSummary"));
        }else
        {
        	hotelSummaryList = (List<Map<String,Object>>)hotelListMap.get("HotelSummary");
        }
        
        for(int i = 0; i < hotelSummaryList.size();i++){
        	Map<String,Object> hotelSummary = (Map<String,Object>)hotelSummaryList.get(i);
        	
        	int popularity = (int)Double.parseDouble(hotelSummary.get("tripAdvisorRating").toString());
        	int distance = 0;
        	int review = (int)Double.parseDouble(hotelSummary.get("tripAdvisorReviewCount").toString());
         	Hotel hotel = new Hotel(hotelSummary.get("hotelId") + "",(String)hotelSummary.get("name"),(String)hotelSummary.get("city"),(int)(Double.parseDouble(hotelSummary.get("lowRate").toString())),(int)(Double.parseDouble(hotelSummary.get("hotelRating").toString())),null,
					new HotelImage("http://images.travelnow.com"+(String)hotelSummary.get("thumbNailUrl"), null),new StarValue(popularity, distance, review),null);
         	hotelMapper.put(hotel.getHotelId(),hotel);
        }
	}    
	
	public List<Hotel> getAllHotels(SearchBean searchBean) { 
		
		try{
			createHotelMap(map);
		}catch(Exception e){
			e.printStackTrace();
		}
		
		List<Hotel> hotelList = new ArrayList<Hotel>();
		
		Collection<Hotel> hotelCollections = hotelMapper.values();
		
		Iterator<Hotel> iterator = hotelCollections.iterator();
		
		Date checkinDate = searchBean.getPlaceBean().getFromDate();
		Date checkoutDate = searchBean.getPlaceBean().getFromDate(); 
		
		while(iterator.hasNext()){
			Hotel tmphotel = iterator.next();
			hotelList.add(tmphotel);
			Deal tmpDeal = DealMap.getInstance().getDealForHotel(tmphotel.getHotelId());
			
			if(tmpDeal == null){
				continue;
			}
			if(checkinDate != null && checkoutDate != null){
				if(tmpDeal.insideRange(checkinDate, checkoutDate)){
					tmphotel.setHasDeal(true);
				}
			}else
			if(checkinDate == null && checkoutDate != null)
			{
				if(tmpDeal.insideRange(checkoutDate)){
					tmphotel.setHasDeal(true);
				}
			}else
			if(checkinDate != null && checkoutDate == null)
			{
				if(tmpDeal.insideRange(checkinDate)){
					tmphotel.setHasDeal(true);
				}
			}else
			{
				tmphotel.setHasDeal(true);
			}
			
			
		}
		
		
		return hotelList;
	}
	
	public List<Hotel> getHotels(String hotelsIds){ 
		
		String[] hotelIdArr = hotelsIds.split(",");
		List<Hotel> hotelList = new ArrayList<Hotel>();
		for(int i = 0; i < hotelIdArr.length; i++){
			if(hotelMapper.containsKey(hotelIdArr[i])){
				hotelList.add(hotelMapper.get(hotelIdArr[i]));
			}
		}
		
		return hotelList;
	}	
	
	public void setHotelMapper(List<Hotel> hotelList){
		
		for(int i = 0; i < hotelList.size(); i++){
			System.out.println("HOTEL ID    " + hotelList.get(i).getHotelId());
			hotelMapper.put(hotelList.get(i).getHotelId(), hotelList.get(i));
		}
		
		System.out.println("SETTING HITELL MAPPER  " + hotelMapper);
	}
	
	public Hotel getHotel(String hotelId){
		System.out.println("HOTEL ID   GETTING  " + hotelMapper);
		Hotel hotel = this.hotelMapper.values().stream().filter(a -> a.getHotelId().trim()== hotelId.trim()).collect(Collectors.toList()).get(0);
		return hotel;
	}
	
}
